/*
 *  Class name: EditorController.java
 *  Version: 1.0
 *  Date: 21.6.2014
 */
package cz.morosystems.personwebmanager.presentationlayer.controllers;

import cz.morosystems.personwebmanager.businesslayer.sevices.AccountService;
import cz.morosystems.personwebmanager.businesslayer.sevices.BookService;
import cz.morosystems.personwebmanager.businesslayer.sevices.UserService;
import cz.morosystems.personwebmanager.persistencelayer.entities.Account;
import cz.morosystems.personwebmanager.persistencelayer.entities.Book;
import cz.morosystems.personwebmanager.persistencelayer.entities.User;
import cz.morosystems.personwebmanager.presentationlayer.controllers.utils.EditorControllerHelper;
import cz.morosystems.personwebmanager.presentationlayer.propertyeditors.AccountPropertyEditor;
import cz.morosystems.personwebmanager.presentationlayer.propertyeditors.BookPropertyEditor;
import java.util.Locale;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

/**
 *
 * @author Michal Ďuriš
 */
@Controller
@RequestMapping("/admin/editor")
public class EditorController {
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private BookService bookService;
    
    @Autowired
    private AccountService accountService;
    
    public EditorController() {
    }
    
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        
        BookPropertyEditor bookEditor = new BookPropertyEditor();
        bookEditor.setBookService(bookService);
        
        AccountPropertyEditor accountEditor = new AccountPropertyEditor();
        accountEditor.setAccountService(accountService);
        
        binder.registerCustomEditor(Book.class, 
                bookEditor);
        binder.registerCustomEditor(Account.class, 
                accountEditor);
    }
    
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public String addUser(Model model) {
        
        model.addAttribute("user", new User());
        
        return EditorControllerHelper.redirectToEditorView("user");
    }
    
    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String addUser(@Valid @ModelAttribute("user") User user,
                          BindingResult result) {
        
        if (result.hasErrors()) {
            return EditorControllerHelper.redirectToEditorView("user");
        }
        
        userService.addUser(user);
        
        return EditorControllerHelper.REDIRECT_HOME;
    }
    
    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public String changeUser(@PathVariable Long id, Model model) {

        model.addAttribute("user", userService.getUserByID(id));
        
        return EditorControllerHelper.redirectToEditorView("user");
    }
    
    @RequestMapping(value = "/user/{id}", method = RequestMethod.POST)
    public String changeUser(@Valid @ModelAttribute("user") User user,
                             BindingResult result) {
        
        User storedUser = userService.getUserByID(user.getId());
        
        user.setBooks(storedUser.getBooks());
        user.setAccounts(storedUser.getAccounts());
        
        if (result.hasErrors()) {
            
            return EditorControllerHelper.redirectToEditorView("user");
        }
        
        userService.changeUser(user);
        
        return EditorControllerHelper.REDIRECT_HOME;
    }
    
    @RequestMapping(value = "/delete/user/{id}")
    public String deleteUser(@PathVariable Long id) {
        
        userService.deleteUser(id);
        
        return EditorControllerHelper.REDIRECT_HOME;
    }
    
    @RequestMapping(value = "/{subentity}", method = RequestMethod.GET,
                    params = "userID")
    public String addSubentity(@PathVariable String subentity, Model model) {
        
        switch (subentity.toLowerCase(Locale.ROOT)) {
            
            case "book":
                model.addAttribute("book", new Book());
                break;
            
            case "account":
                model.addAttribute("account", new Account());
                break;
            
            default:
                return "notfound";
        }
        
        return EditorControllerHelper.redirectToEditorView(subentity);
    }
    
    @RequestMapping(value = "/{subentity}/{id}", method = RequestMethod.GET)
    public String changeSubentity(@PathVariable("subentity") String subentity,
                                  @PathVariable("id") Long id,
                                  Model model) {
        
        switch (subentity.toLowerCase(Locale.ROOT)) {
            
            case "book":
                model.addAttribute("book", bookService.getBookByID(id));
                break;
            
            case "account":
                model.addAttribute("account", accountService.getAccountByID(id));
                break;
            
            default:
                return "notfound";
        }
        
        return EditorControllerHelper.redirectToEditorView(subentity);
    }
    
    @RequestMapping(value = "/delete/{subentity}/{id}", params = "userID")
    public String deleteSubentity(@PathVariable("subentity") String subentity,
                                  @PathVariable("id") Long subentityID,
                                  @RequestParam Long userID) {
        
        switch (subentity.toLowerCase(Locale.ROOT)) {
            
            case "book":
                bookService.deleteUsersBook(userID, subentityID);
                break;
            
            case "account":
                accountService.deleteUsersAccount(userID, subentityID);
                break;
            
            default:                
                return "notfound";
        }
        
        return EditorControllerHelper.redirectToUserView(userID);
    }
    
    @RequestMapping(value = "/book", method = RequestMethod.POST)
    public String addBook(@Valid @ModelAttribute("book") Book book,
                          BindingResult result,
                          @RequestParam("userID") Long id) {
        
        if (result.hasErrors()) {
            return EditorControllerHelper.redirectToEditorView("book");
        }
        
        bookService.addUsersBook(id, book);
        
        return EditorControllerHelper.redirectToUserView(id);
    }
    
    @RequestMapping(value = "/account", method = RequestMethod.POST,
                    params = "userID")
    public String addAccount(@Valid @ModelAttribute("account") Account account,
                             BindingResult result,
                             @RequestParam("userID") Long id) {
        
        if (result.hasErrors()) {
            return EditorControllerHelper.redirectToEditorView("account");
        }
        
        accountService.addUsersAccount(id, account);
        
        return EditorControllerHelper.redirectToUserView(id);
    }
    
    @RequestMapping(value = "book/{id}", method = RequestMethod.POST,
                    params = "userID")
    public String changeBook(@Valid @ModelAttribute("book") Book book,
                             BindingResult result,
                             @RequestParam Long userID) {
        
        if (result.hasErrors()) {
            return EditorControllerHelper.redirectToEditorView("book");
        }
        
        bookService.changeBook(book);
        
        return EditorControllerHelper.redirectToUserView(userID);
    }
    
    @RequestMapping(value = "account/{id}", method = RequestMethod.POST,
                    params = "userID")
    public String changeAccount(@Valid @ModelAttribute("account") Account account, 
                                BindingResult result, 
                                @RequestParam Long userID) {
        
        if (result.hasErrors()) {
           return EditorControllerHelper.redirectToEditorView("account");
        }
        
        accountService.changeAccount(account);
        
        return EditorControllerHelper.redirectToUserView(userID);
    }
}
